﻿using Common.Communication;
using Common.Device.DeviceDb;
using Common.Device.Interfaces;
using Common.Tool.DataTools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static NPOI.SS.Formula.Functions.Countif;

namespace DianYuan.DC
{
    public class DP811NiVisa : NiVisaBase, IDianYuan
    {
        public string Name { get; set; }
        public DP811NiVisa(UseDevice device) : base("USB0::0x1AB1::0x0E11::"+device.parameter+ "::INSTR", 1500)
        {
            Name = device.name;
        }

        public Result<double> GetCurrent(int channel = 1)
        {
            lock (this)
            {
                string command = "";
                double cur = 0f;
                var result = new Result<double>();
                var write = new Result();
                var read = new Result<string>();
                AppendInfo(Name, $"通道{channel}读取当前电流");
                command = GetCur;
                //发送指令并返回
                read = WriteThenRead(command);
                if (!read.IsSucceed || !double.TryParse(read.Value, out cur))
                {
                    result.IsSucceed = false;
                    result.Err = "读取当前电流失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                result.Value = cur;
                AppendResult(Name, DataConvert.ToUnit(cur, "F3") + "A");
                return result.EndTime();
            }
        }

        public Result<double> GetPower(int channel = 1)
        {
            lock (this)
            {
                Result<double> result = new Result<double>();
                result.IsSucceed = false;
                result.Err = "暂不支持";
                return result.EndTime();
            }
        }

        public Result<double> GetVoltage(int channel = 1)
        {
            lock (this)
            {
                string command = "";
                double vol = 0f;
                var result = new Result<double>();
                var read = new Result<string>();
                AppendInfo(Name, $"读取当前电压");
                command = GetVol;
                //发送指令并返回
                read = WriteThenRead(command);
                if (!read.IsSucceed || !double.TryParse(read.Value, out vol))
                {
                    result.IsSucceed = false;
                    result.Err = "读取当前电压失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                result.Value = vol;
                AppendResult(Name, DataConvert.ToUnit(vol, "F3") + "V");
                return result.EndTime();
            }
        }

        public Result<bool> SetOff(int channel = 1)
        {
            lock (this)
            {
                string command = "";
                var result = new Result<bool>();
                var write = new Result();
                var read = new Result<string>();
                AppendInfo(Name, $"关闭输出");
                command = Close();
                write = Write(command);
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "关闭输出失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, "关闭输出成功");
                return result.EndTime();
            }
        }

        public Result<bool> SetOn(double vol, double cur = 0, int channel = 1)
        {
            lock (this)
            {
                var result = new Result<bool>();
                var write = new Result();
                var read = new Result<string>();
                AppendInfo(Name, $"通道{channel}设置输出{vol}V,{cur}A");
                AppendInfo(Name, "设置档位");
                write = Write(SetRang(vol > 20));
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "设置档位失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(100);
                //发送指令并返回
                AppendInfo(Name, "设置输出电压");
                write = Write(SetVol(vol));
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "设置输出电压失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                //发送指令并返回
                AppendInfo(Name, "设置输出电流");
                write = Write(SetCur(cur));
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "设置输出电流失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, "打开输出");
                write = Write(OutPut());
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "设置输出电压失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, "打开输出失败");
                return result.EndTime();
            }
        }
        public static string SetRang(bool isHigh)
        {
            if (isHigh)
            {
                return ":VOLT:RANG HIGH\n";
            }
            else
            {
                return ":VOLT:RANG LOW\n";
            }
        }
        public static string SetVol(double vol)
        {
            return "VOLT " + vol.ToString("F3") + "\n";
        }
        public static string GetSetVol { get => "VOLT?\n"; }

        public static string SetCur(double cur)
        {
            return "CURR " + cur.ToString("F3") + "\n";
        }
        public static string GetSetCur { get => "CURR?\n"; }

        public static string OutPut(int channel = 1)
        {
            return $"OUTP CH{channel},ON\n";
        }
        public static string GetOutPutState { get => "OUTP?\n"; }
        public static string OutPutOk { get => "ON"; }

        public static string Close(int channel = 1)
        {
            return $"OUTP CH{channel},OFF\n";
        }
        public static string CloseOk { get => "OFF"; }

        public static string GetVol { get => ":MEAS? CH1\n"; }
        public static string GetCur { get => ":MEAS:CURR? CH1\n"; }
    }
}
